﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace scomA2Proj
{
    public delegate void PriceCutEvent(decimal newPrice);
    public delegate void OrderCompleteEvent(OrderReciept reci);
    public class ChickenFarm
    {
        private int counter = 0;
        private int numRetailers;
        private int maxPriceCuts;
        private decimal currentPrice;

        private int shippingCostPerChicken = 1;
        private decimal taxRate = .09M;
        private PricingModel2 priceModel;
        private MulticellBuffer mcBuff;

        List<Retailer> Retailers = new List<Retailer>();
        List<PriceCutEvent> pces = new List<PriceCutEvent>();
        
        /// <summary>
        /// Constructor for chicken farm.
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="numRetailers"></param>
        /// <param name="maxPriceCuts"></param>
        public ChickenFarm(MulticellBuffer buf, int numRetailers, int maxPriceCuts)
        {
            priceModel = new PricingModel2();
            currentPrice = priceModel.getPrice();            

            this.mcBuff = buf;
            this.maxPriceCuts = maxPriceCuts;
            this.numRetailers = numRetailers;
        }

        /// <summary>
        /// Add the retailer to the pricecutevent delegate
        /// </summary>
        /// <param name="r"></param>
        public void registerRetailer(Retailer r)
        {
            Retailers.Add(r);
            pces.Add(new PriceCutEvent(r.PriceCutEventHandler));
        }
        /// <summary>
        /// The method called to start the ChickenFarmThread that will be used
        /// to create the orderprocessing threads, send events for price changes
        /// </summary>
        /// <param name="maxPriceCuts"></param>
        public void runChickenFarm()
        {
            //chickenfarmthread 
            //1. check price, if lower, send event, counter++, get orders
            
            decimal reportedPrice;
            String strOrderToProcess;
            Order orderObject;            

            while (counter < maxPriceCuts)
            {
                reportedPrice = priceModel.getPrice();
                if (reportedPrice < currentPrice)
                {
                    for (int i = 0; i < numRetailers; i++)
                    {
                        pces[i].BeginInvoke(reportedPrice, null, null);
                    }
                    counter++;
                    currentPrice = reportedPrice;

                    for (int i = 0; i < numRetailers; i++)
                    {
                        strOrderToProcess = mcBuff.getItem();
                        if (strOrderToProcess != null)
                        {
                            //decode string to object
                            orderObject = Order.Decode(strOrderToProcess);

                            //create orderprocessing thread
                            OrderProcessingThread opThread = new OrderProcessingThread(orderObject, taxRate, shippingCostPerChicken, currentPrice);
                            Thread processOrder = new Thread(new ThreadStart(opThread.runOrderProcessingThread));
                            processOrder.Start();
                        }
                        else
                        {
                            throw new Exception("Order string was null");
                        }
                    }
                }
                else
                {
                    currentPrice = reportedPrice;
                    Thread.Sleep(300);
                }                 
            } //end while
        } //end runChickenFarm
    }//end class
}
